<?php
/**
 * 慧用工 提现
 * */

namespace App\Lib;

use Illuminate\Support\Facades\Log;

class Yuque
{
    //配置
    protected $selfConfig = [];

    // 构造
    public function __construct()
    {
        if (env('APP_ENV') != 'product') {
            $this->selfConfig = config('yuque_dev') ?? [];
        } else {
            $this->selfConfig = config('yuque') ?? [];
        }
    }
    
    /*
    * 参数 ASCII 排序
    */
    public function getASCII($data)
    {
        foreach ($data as $k => $v) {
            $Parameters[$k] = $v;
        }
        //按字典序排序参数
        ksort($Parameters);
        $sign = '';
        foreach ($Parameters as $k => $v) {
            $sign .= $k . "=" . $v . "&";
        }
        $sign = rtrim($sign, '&');
        return $sign;
    }

    /**
     * @param $str 字符串
     * @param $privateKey 私钥
     * 生成 sha1WithRSA 签名
     */
    public function getSign($str,$privateKey)
    {
        $privateKey = "-----BEGIN RSA PRIVATE KEY-----\n" .
            wordwrap($privateKey, 64, "\n", true) .
            "\n-----END RSA PRIVATE KEY-----";

        $key = openssl_get_privatekey($privateKey);
        openssl_sign($str, $signature, $key);
        openssl_free_key($key);
        $sign = base64_encode($signature);
        return $sign;
    }

    /**
     * 慧用 加密
     * $option 传递 1
     */
    public function huiYEncrypt($str,$method='AES-128-ECB',$key='您的AESkey',$option)
    {
        $str = openssl_encrypt(json_encode($str), $method, base64_decode($key),$option);
        return $this->binTStr($str);
    }

    /**
     * 2 进制 转为 16进制
     * 加密使用
     */
    public function binTStr($str)
    {
        return strtoupper(bin2hex($str));
    }

    /**
     * AES加密
     */
    public function enAES($txt, $key){
        return base64_encode(openssl_encrypt($txt, 'AES-128-ECB',base64_decode($key), 1));
    }

    /**
     * AES解密
     */
    public function deAES($txt, $key){
        $data = base64_decode($txt);
        return openssl_decrypt($data, 'AES-128-ECB', base64_decode($key), 1);
    }

    /**
     * 慧用 解密
     * $option 传递 1
     */
    function huiYDecrypt($str,$method='AES-128-ECB',$key='您的AESkey',$option)
    {
        $str = $this->strTbin($str);
        return openssl_decrypt($str, $method, base64_decode($key), $option);
    }

    /**
     * desc 16 进制 转为 2进制
     * 解密使用
     */
    function strTbin($hexdata)
    {
        $bindata="";
        for ($i=0;$i < strlen($hexdata);$i+=2) {
            $bindata.=chr(hexdec(substr($hexdata,$i,2)));
        }
        return $bindata;
    }

    /**
     * 请求格式化
     * */
    protected function doCurl($url, $param)
    {
        $url = $this->selfConfig['domain'].$url;

        //参数 ASCII 排序
        $paramV2 = $this->getASCII($param);

        //生成 sha1WithRSA 签名
        $sign = $this->getSign($paramV2, $this->selfConfig['private_key_pkcs1']);
        $param['sign'] = $sign;

        //慧用 加密
        $businessBody = $this->huiYEncrypt($param, 'AES-128-ECB', $this->selfConfig['yuque_private_key'], $this->selfConfig['HY_OPTION']);
        $sendParam['businessBody'] = $businessBody;
        $sendParam['cooperatorId']= $this->selfConfig['cooperatorId'];

        //请求
        $result = curl_request($url, $sendParam, 'json', 'POST');
        $result = json_decode($result, true);
        if(isset($result['statusCode']) && $result['statusCode']==='000000' && isset($result['statusText']) && $result['statusText']==='success'){
            //解析
            $resData = $this->huiYDecrypt($result['data'], 'AES-128-ECB', $this->selfConfig['yuque_private_key'], $this->selfConfig['HY_OPTION']);
            write_log('yuque', 'doCurl', ['url'=>$url, 'param'=>$param, 'sendParam'=>$sendParam, 'result'=>$result, 'resData'=>$resData]);
            $resData = json_decode($resData, true);
            return [
                'code' => 0,
                'msg' => '成功',
                'data' => $resData,
            ];
        }else{
            write_log('error_yuque', 'doCurl 状态码异常', ['url'=>$url, 'param'=>$param, 'sendParam'=>$sendParam, 'result'=>$result]);
            return [
                'code' => empty($result['statusCode']) ? -1 : $result['statusCode'],
                'msg' => empty($result['statusText']) ? -1 : $result['statusText'],
                'data' => [],
            ];
        }
    }

    /**
     * 回调解密
     * */
    public function strHuiYDecrypt($cooperatorId, $businessBody)
    {
        if($cooperatorId !== $this->selfConfig['cooperatorId']) {
            return [];
        }
        $resData = $this->huiYDecrypt($businessBody, 'AES-128-ECB', $this->selfConfig['yuque_private_key'], $this->selfConfig['HY_OPTION']);
        $resData = json_decode($resData, true);

        return $resData;
    }

    /**
     * 下发（打款）接口
     * */
    public function distributeSingleDistribute($body)
    {
        $timestamp = time().'000';//毫秒
        $url = "/api/distribute/singleDistribute";
        $param = [];
        $param['cooperatorId'] = $this->selfConfig['cooperatorId'];//商户id
        $param['positionId'] = $this->selfConfig['positionId'];//任务ID
        $param['timestamp'] = $timestamp;
        $param['workerName'] = $body['workerName'];//收款人姓名
        $param['receiptChannel'] = 20;//支付宝
        $param['workerAccount'] = $body['workerAccount'];//收款人账号
        $param['workerType'] = 1;//身份证
        $param['idNumber'] = $body['idNumber'];//职业者身份证号码
        $param['workerMobile'] = $body['workerMobile'];//职业者手机号码
        $param['distributeAmount'] = $body['distributeAmount'];//打款金额
        $param['requestNo'] = $body['requestNo'];//下发请求单号

        //请求
        $result = $this->doCurl($url, $param);
        if($result['code'] == 0) {
            if(!empty($result['data']['distributeId'])) {
                return $result;
            }else{
                return [
                    'code' => -1,
                    'msg' => '返回值解析失败,请联系开发手动处理',
                    'data' => [],
                ];
            }
        }else{
            return $result;
        }
    }

    /**
     * 查询余额
     * */
    public function cooperatorBalance()
    {
        $timestamp = time().'000';//毫秒
        $url = "/api/cooperator/balance";
        $param = [];
        $param['cooperatorId'] = $this->selfConfig['cooperatorId'];//商户id
        $param['timestamp'] = $timestamp;

        //请求
        $result = $this->doCurl($url, $param);
        if($result['code'] == 0) {
            return $result;
        }else{
            return $result;
        }
    }

}